#ifndef SYMTREE_H
#define SYMTREE_H


#include "ast.h"
#include "trace.h"

/* sym tree structure represent the symbol table
 * but in a hierarchical way
 */
struct symTree {
  /* type of element basicaly AT_FUNC, AT_VAR, AT_ARGS */
  int nodeType;
  /* type of value contained in the node */
  int typeVal;
  /* the string value of the item */
  char * sval;
  /* the int value of the item */
  int ival;
  /* the boolean value of the item */
  int bval;
  /* a switch used for the function forward definition
   * this item will be set to 1 if it's function forward definition
   * otherwise it will be 0
   */
  int isForward;
  /* give the depth of the item in the tree */
  int scope;
  /* a pointer to the next element of the list within wich the node is included*/
  struct symTree * next;

  struct symTree * previous;
  /* the list of arguments of a function node */
  struct symTree * args;
  /* the list of function of a function node */
  struct symTree * func;
  /* the list of variable of a function node */
  struct symTree * var;
  /* a pointer to the parent node only used for the function node */
  struct symTree * parent;
  
    char * ASTaddr;
    int location;
    
    
};


typedef struct symTree  SYMTREENODE;
typedef SYMTREENODE * SYMTREE;

extern void printSymTree(SYMTREE tree);

/** builder of symTree */
extern SYMTREE createSymTree();

/** Add a valid node to a sym tree */
extern int add(SYMTREE tree, SYMTREE node, int deeper);

/** search a specific function based on the astnode of the function
 * in the list of all the function of the current sym. the search is limited
 * to one level don't go deeper in the tree
 */
extern SYMTREE searchFunctionCalled(SYMTREE tree, ASTTREE node);

/** Searching for variables only based on its name and its type
 * if the variable doesn't exist in the current context it will look
 * in the inherited variable.
 */
extern SYMTREE varSearch(SYMTREE tree, char * name, int type);


/** search a specific argument based on the astnode of the function
 * in the list of all the arguments of the current sym.
 */
extern SYMTREE argsSearch(SYMTREE tree, ASTTREE node);

/** count the number of argument */
extern int numberOfArguments(SYMTREE tree);

extern SYMTREE searchVarAtCurrentLevel(SYMTREE tree, char * name);

/** free the sym structure */
extern void freeSymTree(SYMTREE symTree);

extern SYMTREE varSearchWithoutType(SYMTREE tree, char * name);

extern SYMTREE searchForVarOrArgWithoutType(SYMTREE tree, char * name);


//return the location of function or variable at address node->addr
extern int LocationSearch(SYMTREE tree, ASTTREE node);
//return the type of function or variable at address node->addr
extern int TypeSearch(SYMTREE tree, ASTTREE node);
extern int getMaxMemoryUsage(SYMTREE s ) ;


extern SYMTREE searchFunctionDefinition(SYMTREE sym, ASTTREE node);


#endif
